<template>
    <div class="tooltip-wrapper">
        <div ref="triggerRef" @mouseenter="handleMouseEnter" @mouseleave="handleMouseLeave" @click="handleClick">
            <slot name="trigger"></slot>
        </div>

        <transition name="fade">
            <div v-if="isVisible" ref="tooltipRef" class="tooltip-content" :class="[placementClass, customClass]"
                :style="contentStyle">
                <slot name="content">
                    {{ content }}
                </slot>
            </div>
        </transition>
    </div>
</template>

<script setup lang="ts">
import { ref, computed, onMounted, onUnmounted } from 'vue'
import { debounce } from 'lodash-es'
import type { Placement } from './types'

interface Props {
    content?: string
    placement?: Placement // 'top' | 'bottom' | 'left' | 'right'
    trigger?: 'hover' | 'click'
    delay?: number
    showArrow?: boolean
    customClass?: string
}

const props = withDefaults(defineProps<Props>(), {
    content: '',
    placement: 'top',
    trigger: 'hover',
    delay: 200,
    showArrow: true,
    customClass: ''
})

const isVisible = ref(false)
const triggerRef = ref<HTMLElement | null>(null)
const tooltipRef = ref<HTMLElement | null>(null)

// 计算定位样式
const placementClass = computed(() => `tooltip-${props.placement}`)

const contentStyle = computed(() => ({
    '--tooltip-delay': `${props.delay}ms`,
    '--arrow-display': props.showArrow ? 'block' : 'none'
}))

// 显示/隐藏逻辑（带防抖）
let timeoutId: number | null = null

const handleMouseEnter = () => {
    if (props.trigger === 'hover') {
        timeoutId = window.setTimeout(() => {
            isVisible.value = true
            updatePosition()
        }, props.delay)
    }
}

const handleMouseLeave = () => {
    if (timeoutId) {
        clearTimeout(timeoutId)
        timeoutId = null
    }
    isVisible.value = false
}

const handleClick = () => {
    if (props.trigger === 'click') {
        isVisible.value = !isVisible.value
        updatePosition()
    }
}

// 动态计算定位
const updatePosition = debounce(() => {
    if (!triggerRef.value || !tooltipRef.value) return

    const triggerRect = triggerRef.value.getBoundingClientRect()
    const tooltipRect = tooltipRef.value.getBoundingClientRect()

    switch (props.placement) {
        case 'top':
            tooltipRef.value.style.left = `${triggerRect.left + triggerRect.width / 2 - tooltipRect.width / 2}px`
            tooltipRef.value.style.top = `${triggerRect.top - tooltipRect.height - 8}px`
            break
        case 'bottom':
            // 其他定位计算类似
            break
        // ...其他定位处理
    }
},100)

// 窗口变化监听
const resizeObserver = new ResizeObserver(updatePosition)

onMounted(() => {
    if (triggerRef.value) {
        resizeObserver.observe(triggerRef.value)
    }
})

onUnmounted(() => {
    resizeObserver.disconnect()
})
</script>

<style scoped>
.tooltip-wrapper {
    position: relative;
    display: inline-block;
}

.tooltip-content {
    position: fixed;
    background: #333;
    color: white;
    padding: 6px 12px;
    border-radius: 4px;
    font-size: 14px;
    z-index: 9999;
    transition: opacity var(--tooltip-delay) ease;
    pointer-events: none;
}

.tooltip-content::after {
    content: '';
    position: absolute;
    border-width: 5px;
    border-style: solid;
    display: var(--arrow-display);
}

/* 定位样式 */
.tooltip-top::after {
    top: 100%;
    left: 50%;
    transform: translateX(-50%);
    border-color: #333 transparent transparent transparent;
}

/* 其他定位样式... */

.fade-enter-active,
.fade-leave-active {
    transition: opacity 0.2s;
}

.fade-enter-from,
.fade-leave-to {
    opacity: 0;
}
</style>